#include "AnimationManager.h"






CAnimationManager::CAnimationManager(void)
{

}


CAnimationManager::~CAnimationManager(void)
{
	m_vAnimation.clear();
}

CAnimationManager* CAnimationManager::GetInstance( void )
{

	// Lazy Instantiation
	static CAnimationManager s_Instance;

	return &s_Instance;
}
//need to add a file name to each?
void CAnimationManager::Update( float fElapsedTime,CAnimationMenu &AniInfo)
{
	//passing in animation name and animation information.
	AniInfo.ModTime(fElapsedTime);
	float FrameDuration =this->m_mapAnimations[AniInfo.m_nCurrentAnimation]->m_vFrames[AniInfo.m_nCurrentFrame]->GetFrameDuration();
	int FrameCount =this->m_mapAnimations[AniInfo.m_nCurrentAnimation]->GetFrameCount();


	if(FrameDuration<AniInfo.GetFrameTime())
	{
		AniInfo.ModFrame(1);
		AniInfo.SetTime(0);
		if(AniInfo.GetCurrentFrame()>=FrameCount)
		{
			if(this->m_mapAnimations[AniInfo.m_nCurrentAnimation]->GetLooping() ==true)
			{
				AniInfo.SetFrame(0);
			}
			else
			{
				AniInfo.SetName(AniInfo.GetNext());
			}
		}
		string EventTrigger = this->m_mapAnimations[AniInfo.m_nCurrentAnimation]->m_vFrames[AniInfo.m_nCurrentFrame]->GetEventTrigger();
		if(EventTrigger!="NO")
		{
			CEventSystem* self = CEventSystem::GetInstance();
			self->SendEvent(EventTrigger);
		}
	}

}

void CAnimationManager::Render( CAnimationMenu AniInfo,int nX, int nY,float fScale,bool bFlipped )
{
	//passing in animation name and animation information.
	m_pTM = CSGD_TextureManager::GetInstance();

	//need to change this up so It can look up animation base on a passed in current information.
	// boolfliped and xscale
	// posx - (anchorx * xscale)
	POINT ptAnchor =this->m_mapAnimations[AniInfo.m_nCurrentAnimation]->m_vFrames[AniInfo.m_nCurrentFrame]->GetAnchorPoint();
	int ImageID =this->m_mapAnimations[AniInfo.m_nCurrentAnimation]->GetImageID();
	RECT Source =this->m_mapAnimations[AniInfo.m_nCurrentAnimation]->m_vFrames[AniInfo.m_nCurrentFrame]->GetSourceRect();
	int PosX  =0;
	int PosY  =0;

	float fXScaled = fScale;
	if(bFlipped == true)
	{
		fXScaled = -fXScaled;
	
	 PosX = nX- int((ptAnchor.x+GetCWidth(AniInfo))* fXScaled);
	 PosY = nY- int((ptAnchor.y-GetCHeight(AniInfo)) * fScale);
	}
	else
	{
	PosX = nX- int((ptAnchor.x-GetCWidth(AniInfo))* fXScaled);
	PosY = nY- int((ptAnchor.y-GetCHeight(AniInfo)) * fScale);
	}
	//Get height/width calcuated in?
	if(m_vAnimation.size()!=0)
	{
		m_pTM->Draw(ImageID,PosX,PosY,fXScaled,fScale,&Source);
	}
}

bool CAnimationManager::LoadFile(const char* szPath)
{
	TiXmlDocument doc;

	if( doc.LoadFile( szPath ) == false )
		return false;

	TiXmlElement* pRoot = doc.RootElement();

	if( pRoot == nullptr )
		return false;

	TiXmlElement * pNodeFrame  = pRoot->FirstChildElement("Animation");
	int AnimationId=0;

	while( pNodeFrame != nullptr )
	{
		//get image ID
		//get number of animations

		//for each animation in loader look for that value

		string AniName = pNodeFrame->Attribute("Name");
		//get number of frames
		int FrameCount;
		pNodeFrame->Attribute("FrameCount",(int*)&FrameCount);
		bool looping;
		string checker = "true";
		if(checker == "true")
		{
			looping=true;
		}
		else
			looping=false;
		int ImageId;
		TCHAR  	bufferA[ 1000 ];
		const char* ImageIdPath;

		ImageIdPath=pNodeFrame->Attribute("ImageId");
		mbstowcs_s(nullptr,bufferA, 1000,  ImageIdPath, _TRUNCATE );

		m_pTM = CSGD_TextureManager::GetInstance();
		//get id back from texture manager.
		//TODO
		ImageId=m_pTM->LoadTexture(bufferA,D3DCOLOR_XRGB(255,255,255));

		CAnimation* TempAnimation = new CAnimation();//or could make a singleton...
		TempAnimation->SetLooping(looping);
		TempAnimation->SetName(AniName);
		TempAnimation->SetAnimationID(AnimationId);
		AnimationId++;

		TempAnimation->SetImageID(ImageId);//setimageid
		TempAnimation->SetFrameCount(FrameCount);//setframecount




		TiXmlElement * pNode  = pNodeFrame->FirstChildElement("Frame");

		//for each frame in animation

		for(int i=0;i<FrameCount;i++)
		{

			CAnimationFrame* TempFrame = new CAnimationFrame();

			//TempFrame->SetFrameID(i);

			TiXmlElement* pNodeAnimation = pNode->FirstChildElement( "SourceRECT" );
			int L,T,R,B;

			pNodeAnimation->Attribute("RenderLeft",			&L);
			pNodeAnimation->Attribute("RenderTop",			&T);
			pNodeAnimation->Attribute("RenderRight",		&R);
			pNodeAnimation->Attribute("RenderBottom",		&B);
			TempFrame->SetSourceRect(L,T,R,B);

			B=L=R=T=0;
			pNodeAnimation = pNode->FirstChildElement( "CollisionRECT" );

			pNodeAnimation->Attribute(	"CollisionLeft",	&L);
			pNodeAnimation->Attribute(	"CollisionTop",		&T);
			pNodeAnimation->Attribute(	"CollisionRight",	&R);
			pNodeAnimation->Attribute(	"CollisionBottom",	&B);
			TempFrame->SetCollisionRect(L,T,R,B);


			B=L=R=T=0;
			pNodeAnimation = pNode->FirstChildElement( "AttackRECT" );
			pNodeAnimation->Attribute(	"AttackLeft",		&L);
			pNodeAnimation->Attribute(	"AttackTop",		&T);
			pNodeAnimation->Attribute(	"AttackRight",		&R);
			pNodeAnimation->Attribute(	"AttackBottom",		&B);
			TempFrame->SetAttackRect(L,T,R,B);


			pNodeAnimation = pNode->FirstChildElement( "Data" ); //need to fix this up in the xml 
			/*
			includes AnchortPoint, durration, and event string
			*/
			int X=0;	int Y=0;
			float times =0;
			string  Triggers;
			pNodeAnimation->Attribute("AnchorX",&X);
			pNodeAnimation->Attribute("AnchorY",&Y);
			pNodeAnimation->QueryFloatAttribute("Duration",&times);
			Triggers=pNodeAnimation->Attribute("EventTrigger");
			TempFrame->SetAnchorPoint(X,Y);
			TempFrame->SetFrameDuration(times);
			TempFrame->SetEventTrigger(Triggers);

			TempAnimation->m_vFrames.push_back(TempFrame);

			pNode  = pNode->NextSiblingElement("Frame");
		}
		//once all frames are in the animation
		this->m_vAnimation.push_back(TempAnimation);

		pNodeFrame = pNodeFrame->NextSiblingElement( "Animation");
		//and start the next one
	}

	return false;
}

bool CAnimationManager::SetMap( void )
{
	if(m_vAnimation.size()!=0)
	{
		for(unsigned int i=0;i<this->m_vAnimation.size();i++)
		{
			std::pair<string,CAnimation*> Value;
			Value.first=m_vAnimation[i]->GetAnimationName();
			Value.second=m_vAnimation[i];
			this->m_mapAnimations.insert(Value);

		}
		return true;
	}
	else
		return false;
}

void CAnimationManager::Exit( void )
{
	for(unsigned int i=0; i< this->m_vAnimation.size();i++)
	{
		if(this->m_vAnimation[i]->GetAnimationID()!=-1)
		{
			m_pTM->UnloadTexture(this->m_vAnimation[i]->GetImageID());
			this->m_vAnimation[i]->SetImageID(-1);
		}

		for(unsigned int e =0; e<m_vAnimation[i]->m_vFrames.size();e++)
		{
			delete this->m_vAnimation[i]->m_vFrames[e];
		}	
		delete this->m_vAnimation[i];
	}



}

RECT CAnimationManager::GetCRECT(CAnimationMenu &AniInfo,int X,int Y)
{
	POINT ptAnchor =this->m_mapAnimations[AniInfo.GetName()]->m_vFrames[AniInfo.GetCurrentFrame()]->GetAnchorPoint();

	RECT Source =this->m_mapAnimations[AniInfo.GetName()]->m_vFrames[AniInfo.GetCurrentFrame()]->GetCollsionRect();

	int CollideWidth =  Source.right-Source.left;
	int CollideHeight = Source.bottom-Source.top;

	int AnchorXoffset = ptAnchor.x-Source.left ;
	int AnchorYoffset = ptAnchor.y- Source.top;
	
	int TRLeft = X+AnchorXoffset;
	int TRTop = Y;// AnchorYoffset-Y;
	int TRRight = TRLeft +CollideWidth;
	int TRBot =TRTop+CollideHeight;
	RECT ToReturn = {TRLeft,TRTop,TRRight,TRBot};

	return ToReturn;
}

int  CAnimationManager::GetCWidth(CAnimationMenu &AniInfo)
{
//	POINT ptAnchor =this->m_mapAnimations[AniInfo.m_nCurrentAnimation]->m_vFrames[AniInfo.m_nCurrentFrame]->GetAnchorPoint();

	RECT Source =this->m_mapAnimations[AniInfo.m_nCurrentAnimation]->m_vFrames[AniInfo.m_nCurrentFrame]->GetSourceRect();

	int CollideWidth =  Source.right-Source.left;

	return CollideWidth;
}

int  CAnimationManager::GetCHeight(CAnimationMenu &AniInfo)
{
	//POINT ptAnchor =this->m_mapAnimations[AniInfo.m_nCurrentAnimation]->m_vFrames[AniInfo.m_nCurrentFrame]->GetAnchorPoint();
	string tempstring = AniInfo.m_nCurrentAnimation;
	int tempint = AniInfo.m_nCurrentFrame;

	RECT Source =this->m_mapAnimations[tempstring]->m_vFrames[tempint]->GetSourceRect();

	int CollideHeight = Source.bottom-Source.top;

	return CollideHeight;
}
